package org.jspresso.framework.application.backend.persistence.hibernate;

import org.hibernate.SessionFactory;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.jspresso.framework.action.ActionBusinessException;
import org.jspresso.framework.application.backend.ControllerAwareTransactionTemplate;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
import org.springframework.transaction.support.TransactionTemplate;

public class TestHibernateBackendController extends HibernateBackendController implements ApplicationContextAware {

	private SessionFactory      standardHibernateSessionFactory;
	private SessionFactory      testHibernateSessionFactory;
	private TransactionTemplate testTransactionTemplate;
	private boolean 			testSituation = false;
	private ApplicationContext context;

	@Override
	public void setHibernateSessionFactory(SessionFactory hibernateSessionFactory) {
		this.standardHibernateSessionFactory = hibernateSessionFactory;
	}

	public void setTestHibernateSessionFactory(SessionFactory hibernateSessionFactory) {
		this.testHibernateSessionFactory = hibernateSessionFactory;
	}

	@Override
	protected SessionFactory getHibernateSessionFactory() {
		if(testSituation) {
			return testHibernateSessionFactory;
		}
		return standardHibernateSessionFactory;
	}

	@Override
	public TransactionTemplate getTransactionTemplate() {
		if(testSituation) {
			return testTransactionTemplate;
		}
		return super.getTransactionTemplate();

	}

	public void setTestSituation(boolean isTestSituation) {
		if(isUnitOfWorkActive()) {
			throw new ActionBusinessException("Cannot change data source while UOW is active.");
		}
		this.testSituation = isTestSituation;
	}

	public void clearTestDataSourceContent() {		

		LocalSessionFactoryBean session =  (JspressoLocalSessionFactoryBean) context.getBean("&testHibernateSessionFactory");;
		SchemaExport export = new SchemaExport(session.getConfiguration());
		export.drop(false, true);
		export.create(false, true);
	}

	public void setTestTransactionTemplate(TransactionTemplate testTransactionTemplate) {
		if (this.testTransactionTemplate != null) {
			throw new IllegalArgumentException(
					"Spring test transaction template can only be configured once.");
		}
		if (testTransactionTemplate != null
				&& !(testTransactionTemplate instanceof ControllerAwareTransactionTemplate)) {
			throw new IllegalArgumentException(
					"You have configured a test transaction template that is not a controller "
							+ "aware transaction template. This is not legal since this prevents "
							+ "the Unit of Work to be synchronized with the current transaction.");
		}
		this.testTransactionTemplate = testTransactionTemplate;
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		context = applicationContext;
	}

}
